/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = wtc_tcb_ws.c                                       */
/*  NOTE      =                                                    */
/*  DATE      = 2015/08/27 by songbb                               */
/*******************************************************************/

#include "conntrack.h"
#include "frct_comm.h"

#include "../wtc_core.h"
#include "../wtc_comm.h"
#include "../wtc_mar.h"
#include "wtc_tcb_ws.h"

int wtc_tcb_ws_tmpostrecv(Conntrack *p_st_conn
                        , Apm_packet *p_analyze_in
                        , L7session_wtc *p_st_sess
                        , L7_wtc_packet *p_st_wtc_packet
                        , int i_recv_size
                        , int i_hint_index)
{
    unsigned int ui_lcv;
    unsigned int ui_flag = 0;
    unsigned int ui_tpevent = 0;
    unsigned int ui_tpexception = 0;
    unsigned int ui_tpurcode = 0;
    unsigned int ui_uunixerr = 0;
    unsigned int ui_tperrordetail = 0;
    unsigned int ui_connindx = 0;
    unsigned int ui_sendmtype = 0;
    unsigned int ui_rplymtype = 0;
    unsigned int ui_appkey = 0;
    unsigned int ui_clt_id = 0;
    unsigned int ui_opcode = 0;
    int i_wsop = 0;
    int i_opcode_flags = 0;
    unsigned int ui_rtn_val = 0;
    unsigned int arr_ui_flds[7] = {0};
    unsigned int ui_r_length = 0;
    int i_r_padded_length = 0;
    char *p_typebyte = NULL;
    uint8_t byte;
    char *p_rqustsrvc = NULL;
    unsigned int ui_rqustsrvc_len = 0;

    i_recv_size -= 80;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_flag, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_tpevent, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_tpexception, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_tpurcode, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_uunixerr, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_tperrordetail, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_connindx, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_sendmtype, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_rplymtype, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_appkey, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_clt_id, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_opcode, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    i_wsop = ui_opcode & 0x3FFFFFFF;
    i_opcode_flags = ui_opcode & 0xC0000000;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_rtn_val, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    for (ui_lcv = 0; ui_lcv < 7; ui_lcv++)
    {
        if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &arr_ui_flds[ui_lcv], BYTE_BIG_ENDIAN) != FR_SUCC)
            goto error;
    }
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_r_length, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    i_recv_size -= 4;
    i_r_padded_length = wtc_mar_roundup4(ui_r_length);
    if (ui_r_length > 0)
    {
        if ((p_typebyte = (char *) frmalloc(ui_r_length * sizeof(char))) == NULL)
        {
            WTC_PRINT_ERR("ui_r_length:[%u]\n", ui_r_length);
            WTC_MALLOCK_ERR;
            goto error;
        }
    }
    for (ui_lcv = 0; ui_lcv < ui_r_length; ui_lcv++)
    {
        if (bytebuff_get_char(p_st_wtc_packet->p_st_packet, &byte) != FR_SUCC)
            goto error;
        p_typebyte[ui_lcv] = byte;
    }
    i_recv_size -= ui_r_length;
    for (; ui_lcv < (unsigned int) i_r_padded_length; ui_lcv++)
    {
        if (bytebuff_get_char(p_st_wtc_packet->p_st_packet, &byte) != FR_SUCC)
            goto error;
    }
    i_recv_size -= i_r_padded_length;
    if (i_recv_size > 0)
    {
        if (bytebuff_skip(p_st_wtc_packet->p_st_packet, (size_t) i_recv_size) != FR_SUCC)
            goto error;
    }

    if (wtc_mar_get_mbstring(p_st_sess->p_default_encoding, p_typebyte, ui_r_length, &p_rqustsrvc, &ui_rqustsrvc_len) != FR_SUCC)
        goto error;

    WTC_PRINT_FATAL("p_rqustsrvc:[%s]\n", p_rqustsrvc);

    wtc_free((void **) &p_typebyte);
    wtc_free((void **) &p_rqustsrvc);
    return FR_SUCC;
error:
    wtc_free((void **) &p_typebyte);
    wtc_free((void **) &p_rqustsrvc);
    return FR_FAIL;
}

int wtc_tcb_ws_tmpostrecv65(Conntrack *p_st_conn
                            , Apm_packet *p_analyze_in
                            , L7session_wtc *p_st_sess
                            , L7_wtc_packet *p_st_wtc_packet
                            , int i_recv_size
                            , int i_hint_index)
{
    int i_lcv;
    unsigned int ui_flag = 0;
    unsigned int ui_tpevent = 0;
    unsigned int ui_tpexception = 0;
    unsigned int ui_tpurcode = 0;
    unsigned int ui_uunixerr = 0;
    unsigned int ui_tperrordetail = 0;
    char arr_rqsvc[16] = {'\0'};
    char *p_rqustsrvc = NULL;
    unsigned int ui_rqustsrvc_len = 0;
    unsigned int ui_connindx = 0;
    unsigned int ui_sendmtype = 0;
    unsigned int ui_rplymtype = 0;
    unsigned int ui_appkey = 0;
    unsigned int ui_clt_id = 0;
    unsigned int ui_opcode = 0;
    int i_wsop = 0;
    int i_opcode_flags = 0;
    unsigned int ui_rtn_val = 0;
    unsigned int arr_ui_flds[7] = {0};
    char arr_typebuf[8] = {'\0'};
    char *p_type = NULL;
    unsigned int ui_type_len = 0;

    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_flag, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_tpevent, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_tpexception, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_tpurcode, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_uunixerr, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    for (i_lcv = 0; i_lcv < 4; i_lcv++)
    {
        if (bytebuff_skip(p_st_wtc_packet->p_st_packet, 32) != FR_SUCC)
            goto error;
    }
    ui_tperrordetail = 0;
    if (wtc_mar_decode_vector_string(p_st_wtc_packet, arr_rqsvc, 16, &p_rqustsrvc, &ui_rqustsrvc_len) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_connindx, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_sendmtype, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_skip(p_st_wtc_packet->p_st_packet, 4) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_rplymtype, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_skip(p_st_wtc_packet->p_st_packet, 4) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_appkey, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_skip(p_st_wtc_packet->p_st_packet, 32) != FR_SUCC)
        goto error;
    if (bytebuff_skip(p_st_wtc_packet->p_st_packet, 64) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_clt_id, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_opcode, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    i_wsop = ui_opcode & 0x3FFFFFFF;
    i_opcode_flags = ui_opcode & 0xC0000000;
    if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &ui_rtn_val, BYTE_BIG_ENDIAN) != FR_SUCC)
        goto error;
    for (i_lcv = 0; i_lcv < 7; i_lcv++)
    {
        if (bytebuff_get_int(p_st_wtc_packet->p_st_packet, 4, &arr_ui_flds[i_lcv], BYTE_BIG_ENDIAN) != FR_SUCC)
            goto error;
    }
    if (wtc_mar_decode_vector_string(p_st_wtc_packet, arr_typebuf, 8, &p_type, &ui_type_len) != FR_SUCC)
        goto error;

    wtc_free((void **) &p_rqustsrvc);
    wtc_free((void **) &p_type);
    return FR_SUCC;
error:
    wtc_free((void **) &p_rqustsrvc);
    wtc_free((void **) &p_type);
    return FR_FAIL;
}


int wtc_tcb_ws_tmpostrecv_fad(char *p_payload
                            , unsigned int ui_payload_len
                            , unsigned int *p_ui_offset
                            , int *p_i_direction
                            , int i_recv_size
                            , int i_hint_index)
{
    unsigned int ui_opcode = 0;
    unsigned int ui_r_length = 0;
    int i_r_padded_length = 0;

    i_recv_size -= 80;
    if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, 4 * 11) != FR_SUCC)
        goto error;
    if (wtc_get_int(p_payload, ui_payload_len, p_ui_offset, &ui_opcode) != FR_SUCC)
        goto error;
    *p_i_direction = wtc_analyze_direction_by_opcode(ui_opcode);
    if (*p_i_direction != FR_DIRECT_UNKNOWN)
        return FR_SUCC;
    if (wtc_skip_int(p_payload, ui_payload_len, p_ui_offset) != FR_SUCC)
        goto error;
    if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, 7 * 4) != FR_SUCC)
        goto error;
    if (wtc_get_int(p_payload, ui_payload_len, p_ui_offset, &ui_r_length) != FR_SUCC)
        goto error;
    i_recv_size -= 4;
    i_r_padded_length = wtc_mar_roundup4(ui_r_length);
    if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, ui_r_length) != FR_SUCC)
        goto error;
    i_recv_size -= ui_r_length;
    if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, i_r_padded_length - ui_r_length) != FR_SUCC)
        goto error;
    i_recv_size -= i_r_padded_length;
    if (i_recv_size > 0)
    {
        if (wtc_skip(p_payload, ui_payload_len, p_ui_offset, i_recv_size) != FR_SUCC)
            goto error;
    }

    return FR_SUCC;
error:
    return FR_FAIL;
}
